package com.zhidian.edm.config;

import com.zhidian.edm.exception.BusinessException;
import com.zhidian.edm.result.ResultResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.stream.Collectors;

/**
 * 全局异常处理
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    // =============================
    // 捕获运行时异常
    // =============================
    @ExceptionHandler(RuntimeException.class)
    public ResultResponse<?> handleRuntimeException(RuntimeException ex) {
        logger.error("业务异常: ", ex);
        return ResultResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage());
    }

    // =============================
    // 捕获自定义业务异常
    // =============================
    @ExceptionHandler(BusinessException.class)
    public ResultResponse<?> handleBusinessException(BusinessException ex) {
        logger.warn("业务异常: {}", ex.getMessage());
        return ResultResponse.fail(ex.getCode(), ex.getMessage());
    }

    // =============================
    // 参数校验异常（@Valid/@Validated）
    // =============================
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultResponse<?> handleValidException(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getFieldErrors()
                .stream()
                .map(e -> e.getField() + ": " + e.getDefaultMessage())
                .collect(Collectors.joining("; "));
        logger.warn("参数校验异常: {}", message);
        return ResultResponse.fail(HttpStatus.BAD_REQUEST.value(), message);
    }

    @ExceptionHandler(BindException.class)
    public ResultResponse<?> handleBindException(BindException ex) {
        String message = ex.getBindingResult().getFieldErrors()
                .stream()
                .map(e -> e.getField() + ": " + e.getDefaultMessage())
                .collect(Collectors.joining("; "));
        logger.warn("参数绑定异常: {}", message);
        return ResultResponse.fail(HttpStatus.BAD_REQUEST.value(), message);
    }

    // =============================
    // 捕获其他异常
    // =============================
    @ExceptionHandler(Exception.class)
    public ResultResponse<?> handleException(Exception ex) {
        logger.error("未知异常: ", ex);
        return ResultResponse.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常，请联系管理员");
    }
}
